perm filename TALK11.SAI[PNT,HE]6 blob
sn#533207 filedate 1980-08-28 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00007 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 ENTRY
C00004 00003 ! PEEK, POKE, STRT11,PEEKARRAY, POKEARRAY
C00009 00004 ! check elf status and communication
C00015 00005 ! routines that make console look like VT05
C00020 00006 ! alinit
C00023 00007 ! sav11,res11
C00025 ENDMK
C⊗;
ENTRY;
BEGIN
DEFINE $TALK11=TRUE;
REQUIRE "HEADER.SAI" SOURCE_FILE;
! DEFINE OUTTST = "OUTSTR";
DEFINE OUTTST = "! ";
INTEGER ELFCHAN; ! Channel number for I/O to ELF;
PROCEDURE COMERR
(STRING MESSG;RECORD_POINTER(ANY_CLASS) CONTXT (NULL_RECORD));
! Non-fatal warnings;
BEGIN
USERERR(0,1,"HAH! "&MESSG);
END;
DEFINE SGNEXT="'4000000"; ! extend sign bit of input data ;
DEFINE OWPW ="0"; ! word for word transfer;
DEFINE TWRJ ="'1000000"; ! two words per word,right justified in each halfword;
DEFINE TWRM ="'2000000"; ! two words per word,in right most 32 bits;
DEFINE TWLM ="'3000000"; ! two words per word,in left most 32 bits;
DEFINE ELFHIADDR="('500000)";
! PEEK, POKE, STRT11,PEEKARRAY, POKEARRAY;
INTEGER MTAPE_PLUS_ELF;
DEFINE ELFMTAPE(ADDR)="CODE(MTAPE_PLUS_ELF,ADDR)";
! peek,poke and peekarray take the actual address on the unibus;
PROCEDURE FILL(INTEGER ADR(0),LEN(ELFHIADDR/2),CNTNTS(0));
BEGIN "fill"
INTEGER ARRAY A[1:2];
DEFINE FILL = "'001000000000";
A[1]←FILL+(ADR LSH -1);
A[2]←(LEN LSH 18)+CNTNTS;
ELFMTAPE(A[1]);
IF NOT _SKIP_ THEN COMERR("Couldn't fill ELF with "&CVOS(CNTNTS));
END;
INTEGER PROCEDURE PEEK(INTEGER ADR);
BEGIN "peek" ! Returns the ELF word at unibus address ADR;
INTEGER ARRAY A[1:2];
DEFINE PEEK = "'002000000000";
A[1]←PEEK+(ADR LSH -1);
ELFMTAPE(A[1]);
IF NOT _SKIP_ THEN COMERR("Couldn't peek at ELF");
RETURN(A[2]);
END "peek";
PROCEDURE POKE(INTEGER ADR, CONTENTS);
BEGIN "poke" ! Stores CONTENTS at unibus address ADR;
DEFINE POKE = "'003000000000";
INTEGER ARRAY A[1:2];
A[1]←POKE+(ADR LSH -1);
A[2]←CONTENTS;
ELFMTAPE(A[1]);
IF NOT _SKIP_ THEN COMERR("Couldn't poke at ELF");
END "poke";
PROCEDURE STRT11(INTEGER STRADR('1000));
BEGIN "strt11" ! Starts 11 at STRADR;
DEFINE START = "'005000000000";
INTEGER ARRAY A[1:2];
INTEGER NOSTART;
NOSTART←PEEK(NOSTRT);
IF NOSTART THEN BEGIN
POKE(NOSTRT,0); PRINT("Did not restart ELF");
RETURN;
END;
A[1]←START;
A[2]←0;
POKE('24,STRADR); ! set starting address;
POKE('26,'340); ! set priority level 7;
ELFMTAPE(A[1]);
IF NOT _SKIP_ THEN COMERR("Couldn't start ELF");
CALL(5,"SLEEP"); ! go sleep fro 5 seconds;
END "strt11";
PROCEDURE POKEARRAY(INTEGER ADR, LTH; INTEGER ARRAY CONTENTS; INTEGER USETBITS(0));
BEGIN "pokearray" ! Sends the CONTENTS[1:LTH] to unibus address ADR
and higher;
INTEGER USETO_WORD,SNDIOWD;
USETO_WORD←'400000400000 + (ADR LSH -1)+USETBITS;
CALLU0("USETO",ELFCHAN,USETO_WORD);
SNDIOWD←IOWD(LTH,LOCATION(CONTENTS[1]));
CALLU0("OUT",ELFCHAN,SNDIOWD);
IF _SKIP_ THEN COMERR("POKEARRAY failed");
END "pokearray";
PROCEDURE PEEKARRAY(INTEGER ADR, LTH; INTEGER ARRAY CONTENTS; INTEGER USETBITS(0));
BEGIN "peekarray" ! Gets the CONTENTS[1:LTH] from unibus address ADR
and higher;
INTEGER USETI_WORD,GETIOWD;
USETI_WORD←'400000400000 +(ADR LSH -1)+USETBITS;
CALLU0("USETI",ELFCHAN,USETI_WORD);
GETIOWD←IOWD(LTH,LOCATION(CONTENTS[1]));
CALLU0("IN",ELFCHAN,GETIOWD);
IF _SKIP_ THEN COMERR("PEEKARRAY failed");
END "peekarray";
! check elf status and communication ;
INTEGER PROCEDURE ELFSTATUS;
BEGIN
INTEGER I,STATUS;
CHKESC_I;
POKE(NOTB11,WAKEUP);
FOR I←1 STEP 1 UNTIL 10 DO
BEGIN
URSCHD;
CALL(0,"SLEEP");
STATUS←PEEK(NOTB11);
IF STATUS≠ASLEEP THEN RETURN(STATUS);
END;
RETURN(STATUS);
END;
BOOLEAN ELF_ASLEEP_PRINTED;
INTEGER PROCEDURE LISTENELF;
BEGIN
INTEGER STATUS;
$ELFABORTED←FALSE;
STATUS←ELFSTATUS;
IF STATUS≠ASLEEP THEN RETURN(STATUS);
IF NOT ELF_ASLEEP_PRINTED THEN
BEGIN
PRINT("ELF is asleep, I will keep trying to wake it",CRLF,
" till you type esc_I to abort",CRLF);
ELF_ASLEEP_PRINTED←TRUE;
END;
DO BEGIN
STATUS←ELFSTATUS;
CHKESC_I;
END UNTIL STATUS≠ASLEEP;
RETURN(STATUS);
END;
PROCEDURE DO_LISTEN;
BEGIN
INTEGER I;
POKE(NOTB10,LISTEN);
ELF_ASLEEP_PRINTED←FALSE; ! make sure print out error ;
DO I←LISTENELF UNTIL I=LISTENING;
END;
INTERNAL PROCEDURE READBUFFERS(STRING SOURCE);
BEGIN INTEGER I;
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
PEEKARRAY(NOTB11,9,NOTBOX);
IF $INTSIZ←(INTPTR-INTBUF)/2 THEN
BEGIN
IF $INTSIZ<0 THEN ERROR(SOURCE& " DISASTER: asking to transfer negative number of integers");
IF $INTSIZ>IBUFFSIZ THEN
ERROR(SOURCE&" DISASTER: trying to transfer too many numbers; probably overran integer buffer");
PEEKARRAY(INTBUF+MAP_OFFSET,INTSIZ,$INBUF,SGNEXT);
END;
IF $FPSIZ←(FPPTR-FPBUF)/4 THEN
BEGIN
IF $FPSIZ<0 THEN
ERROR(SOURCE&" DISASTER: asking to transfer negative number of FP nums");
IF $FPSIZ>FBUFFSIZ THEN
ERROR(SOURCE&" DISASTER: trying to transfer too many numbers; probably overran FP buffer");
PEEKARRAY(FPBUF+MAP_OFFSET,$FPSIZ,TMPBUF,TWLM);
FOR I←1 STEP 1 UNTIL $FPSIZ DO $FPBUF[I]←RFVAL0(TMPBUF[I]);
END;
$FPPTR←$INTPTR←0;
$FPMAX←$FPMAX MAX $FPSIZ;
$INTMAX←$INTMAX MAX $INTSIZ;
END;
PROCEDURE EVALCONT;
BEGIN INTEGER I;
POKE(NOTB10,WORK);
DO IF (I←LISTENELF)=GAVEUP
THEN BEGIN POKE(NOTB10,GOSLEEP);
ERROR("abandoned this instruction midway");
END UNTIL I=DONEWORKING;
READBUFFERS("EVAL ");
POKE(NOTB10,GOSLEEP);
END;
INTERNAL PROCEDURE ZROBUFF;
BEGIN
! force 11 integer and real buffers to be reset to beginning ;
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
PEEKARRAY(NOTB11,9,NOTBOX); ! gets current status;
INTPTR←INTBUF; INTSIZ←0; ! reset pointers;
FPPTR←FPBUF; FPSIZ←0;
POKEARRAY(NOTB11,9,NOTBOX);
END;
INTERNAL PROCEDURE EVAL(RPTR(EXPR$) EE);
BEGIN
$PCDMAX←$PCDMAX MAX (PSIZE←EXPR$:#BODY[EE]);
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
IF !DEBUG AND ¬!!DEBUGGING THEN SETPCDBUF(OLDPCDBUF);
DO_LISTEN;
IF PSIZE>PBUFFSIZ THEN
ERROR("EVAL ERROR: statement pcode size too large");
POKEARRAY(PCDBUF+MAP_OFFSET,PSIZE,EXPR$:BODY[EE]);
EVALCONT;
END;
INTERNAL INTEGER PROCEDURE GETPCDBUF;
RETURN(PCDBUF);
INTERNAL PROCEDURE SETPCDBUF(INTEGER NEWPCDBUF);
BEGIN
PCDBUF← NEWPCDBUF;
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
DO_LISTEN;
POKE(NOTB11+2,NEWPCDBUF);
END;
INTERNAL PROCEDURE RSTR11;
BEGIN
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
SETPCDBUF(OLDPCDBUF);
EVALCONT;
END;
INTERNAL PROCEDURE CONTNU11;
BEGIN
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
SETPCDBUF(PCDPTR); ! PCDPTR is in words;
EVALCONT;
END;
! routines that make console look like VT05;
PRELOAD_WITH 30,'2000/35,'2000/24,'2000/36,'2000/30,'2000/30;
INTEGER ARRAY LINWIDTH[0:MAX_TTY];
SIMPLE INTEGER PROCEDURE YPOS(INTEGER LINE);
RETURN('1000-LINE*LINWIDTH[$TTYTYPE]);
INTEGER ARRAY ADDR[0:'23];
SIMPLE INTEGER PROCEDURE LINEDPOS;
BEGIN
CALLU("PPINFO",ADDR[0]);
RETURN(ADDR[2]LAND '777777);
END;
DEFINE CONSOLE_PP="1"; ! pp 1 for the output of elf ;
DEFINE CONSOLE_MODE=0,VT05_MODE←-1;
DEFINE ELF_OREG='274 ;
DEFINE ELF_IREG='272 ;
DEFINE OUTSW='270;
REQUIRE "SYS:PROCES.DEF" SOURCE_FILE;
BOOLEAN $ELFINT;
SIMPLE PROCEDURE INTELF;
$ELFINT←TRUE;
ITEM READELF_ITEM,WRITEELF_ITEM,DUMMY_ITEM;
ITEMVAR MAINPR_ITEM;
REQUIRE 10 NEW_ITEMS;
PROCEDURE WRITEELF;
BEGIN INTEGER CHAR,VAL;
CHAR←0;
WHILE TRUE DO
BEGIN
WHILE (VAL←PEEK(ELF_IREG))≠0 DO URSCHD;
IF CHAR=CR THEN CHAR←INCHRW
ELSE BEGIN
WHILE (CHAR←INCHRS)<0 DO URSCHD;
IF (CHAR LAND '200) THEN CHAR←CHAR LAND '77;
POKE(ELF_IREG,CHAR);
END
END;
END;
DEFINE INTELF_INX=20;
PROCEDURE READELF;
BEGIN INTEGER CHAR;
WHILE TRUE DO
BEGIN
WHILE NOT $ELFINT DO URSCHD;
POLL;
$ELFINT←FALSE;
ENABLE(INTELF_INX);
CALLV("LEYPOS",LINEDPOS);
CALLV("PPSEL",'400000+CONSOLE_PP);
CHAR←PEEK(ELF_OREG);
POKE(ELF_OREG,0);
OUTCHR(CHAR);
CALLV("PPSEL",'400000);
END;
END;
PROCEDURE INIINTELF;
BEGIN
$ELFINT←FALSE;
intmap(INTELF_INX,INTELF,0); ! set mapping for interrupt handler for ELF;
enable(INTELF_INX); ! enable the interrupt handler;
END;
PROCEDURE ESCAPE_I;
BEGIN
DO URSCHD UNTIL $ESC_I;
TERMINATE(WRITEELF_ITEM);
TERMINATE(READELF_ITEM);
ENABLE(INTELF_INX);
RESUME(MAINPR_ITEM,DUMMY_ITEM,KILLME);
END;
INTERNAL PROCEDURE CONSOLE;
BEGIN ! makes this a console for output of 11 ;
MAINPR_ITEM←MYPROC;
POKE(OUTSW,VT05_MODE); ! clean out vt05 mode;
poke(elf_oreg,0);
INIINTELF;
POKE(OUTSW,CONSOLE_MODE); ! set to CONSOLE mode;
CALLV("PPSEL",'400000+CONSOLE_PP);
CALLV("DPYSIZ",15*'1000+1); ! 20 GLITCHES, 1 line per glitch ;
CALLV("DPYPOS",YPOS(3));
CALLV("PPACT",'400000 LOR ('400000 LSH -CONSOLE_PP));
SCHEDULE_ON_CLOCK_INTERRUPTS;
SPROUT(READELF_ITEM,READELF,RUNME);
CALLV("PPSEL",'400000);
CALLV("DPYPOS",YPOS(19));
CALLV("LEYPOS",LINEDPOS);
END;
INTERNAL PROCEDURE UNCONSOLE;
BEGIN
! change back to VT05;
TERMINATE(READELF_ITEM);
POKE(OUTSW,VT05_MODE);
DISABLE(INTELF_INX);
DISABLE(INTCLK_INX);
CALLV("PPREL",CONSOLE_PP);
END;
INTERNAL PROCEDURE VT05;
BEGIN INTEGER I;
! accepts input from the terminal;
IF PSTATUS(READELF_ITEM)=TERMINATED THEN CONSOLE;
SPROUT(WRITEELF_ITEM,WRITEELF,RUNME);
CALLV("LEYPOS",LINEDPOS);
I←'11000000200; ! turn on noecho bit ;
CALL(IOWD(1,LOCATION(I)+1),"TTYSET");
CALLV("PPSEL",'400000+CONSOLE_PP);
DO BEGIN URSCHD; CALL(1,"SLEEP"); END UNTIL $ESC_I;
$ESC_I←FALSE; ENABLE(INTTTI_INX);
CALLV("PPSEL",'400000);
TERMINATE(WRITEELF_ITEM);
I←'12000000200; ! turn off noecho bit ;
CALL(IOWD(1,LOCATION(I)+1),"TTYSET");
END;
! alinit;
INTERNAL PROCEDURE ALINIT;
BEGIN "init"
INTEGER COUNT, BRCHAR, EOF, FLAG;
INTEGER I, ARMCHAN;
! Initialize the ARM for output;
! '400 on in mode word and EOF←1 to take silent return if not available;
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
EOF←1;
OPEN(ARMCHAN←GETCHAN,"ARM",'400,0,0,COUNT,BRCHAR,EOF);
IF EOF THEN
BEGIN
PRINT("ARM is not available. Do you want to wait? ");
IF (INCHRW lor '40) ≠ "y"
THEN BEGIN
CLRBUF;
PRINT(CRLF&"Do you want to go ahead without the ARM?");
IF (INCHRW LOR '40)≠"y" THEN CALL(0,"EXIT");
$ELFUNAVAILABLE←TRUE;
CLRBUF; RETURN;
END;
CLRBUF; ! Flush anything else typed with the "y";
PRINT(crlf&" Waiting .... ");
DO BEGIN ! Wait for ARM to be free - checking every 1/2 minute;
CALL(30,"SLEEP"); ! Sleep for 30 seconds;
EOF←1;
OPEN(ARMCHAN,"ARM",'400,0,0,COUNT,BRCHAR,EOF);
END UNTIL EOF=0;
PRINT(" Gotcha"&crlf);
END;
! Initialize the ELF for output;
! '400 on in mode word and EOF←1 to take silent return if not available;
EOF←1;
OPEN(ELFCHAN←GETCHAN,"ELF",'417,0,0,COUNT,BRCHAR,EOF);
IF EOF THEN
BEGIN ! This should never happen now that the ELF is sharable, but...;
PRINT("ELF is not available. Do you want to wait? ");
IF (INCHRW lor '40) ≠ "y" THEN CALL(0,"EXIT");
CLRBUF; ! Flush anything else typed with the "y";
PRINT(crlf&" Waiting .... ");
DO BEGIN ! Wait for ELF to be free - checking every 1/2 minute;
CALL(30,"SLEEP"); ! Sleep for 30 seconds;
EOF←1;
OPEN(ELFCHAN←GETCHAN,"ELF",'417,0,0,COUNT,BRCHAR,EOF);
END UNTIL EOF=0;
PRINT(" Gotcha"&crlf);
END;
MTAPE_PLUS_ELF←'072000000000+(ELFCHAN LSH 23);
END "init";
! sav11,res11;
INTERNAL PROCEDURE SAV11(INTEGER ARRAY MEM);
BEGIN
INTEGER I;
POKE(NOTB10,SAVE);
CALL(1,"SLEEP");
DO I←PEEK(NOTB11) UNTIL I=SAVED;
CALL(2,"SLEEP");
PEEKARRAY(0,ELFHIADDR/4,MEM,TWRJ);
END;
INTERNAL PROCEDURE RES11(INTEGER ARRAY MEM);
IF NOT($NOELF OR $ELFUNAVAILABLE) THEN
BEGIN
STRT11('130000); ! start ddt to bring system to rest;
POKEARRAY(0,ELFHIADDR/4,MEM,TWRJ);
END;
INTERNAL PROCEDURE RESTRT11(INTEGER STRADR('1000));
BEGIN
INTEGER I;
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
POKE(SAILID,1);
POKE(OUTSW,VT05_MODE);
STRT11(STRADR);
DO I←LISTENELF UNTIL I=AWAKE;
PEEKARRAY(NOTB11,9,NOTBOX);
END;
END;